/**
  ******************************************************************************
  * File Name          : Connect_Iot.c
  * Description        : This file provides code for the configuration
  *                      of Connect_Iot task function
  *
  * Task Introduction:
  *
  * Connect and upload cloud platform task (Connect_Iot_Task) - Use ESP8266 to send the collected data to Ali Cloud Iot platform 
  *	through at-MQTT instruction. The main peripherals used include: ESP8266 WIFI module, related driver code in eps8266. c/. H, 
  *	uart_printf. c/. H two files, data from Sensor_Data_Queue message queue
  *
  * This section uses two global variables: the Connect_Status_Stucrt structure holds the networking state, and the Upload_SensorDate_struct 
  * structure holds sensor information
  *
  *The functions of this file include: function to connect to the cloud platform, function to obtain network state, function to upload data, 
  * and task function
  ******************************************************************************
 */
  
/* Includes ------------------------------------------------------------------*/
#include "Connect_Iot_Task.h"
#include "ESP8266.h"
#include "UART_Printf.h"
#include "OLED.h"
#include "Get_Sensor_Task.h"

#include <string.h>

#include "cmsis_os.h"
#include "FreeRTOS.h"
#include "task.h"
/* External function declaration----------------------------------------------*/

/* Private macro definitions--------------------------------------------------*/

/* Global variable------------------------------------------------------------*/

/* Network Connection Status */
Internat_Connect_Information_Struct Connect_Status_Stucrt = {0};
/* Structure of sensor data to be reported */
SENSOR_Information_Struct Upload_SensorDate_struct        = {0};
/* 
	Whether the device is successfully connected to alibaba Cloud Iot platform: it is determined that 
	the device is operated independently and the data is displayed locally; Or upload the data to the cloud 
*/
extern uint8_t is_connect_iot;
/* Handle to the gas sensor data message queue */
extern QueueHandle_t Sensor_Data_Queue;
/* Handle to the network status message queue */
extern QueueHandle_t Internet_Status_Queue;

/* Static function definition-------------------------------------------------*/

/* Function definition--------------------------------------------------------*/

/** 
* @description: Use at-MQTT instructions to connect ali Cloud platform 

  The AT instructions sent in sequence are as follows : 

  AT+RST
  AT+RESTORE
  AT+CWMODE=1
  AT+CWJAP="CMCC-y36J","DE3e5SLL"
  AT+CIPSNTPCFG=1,8,"cn.ntp.org.cn","ntp.sjtu.edu.cn","us.pool.ntp.org"
  AT+MQTTUSERCFG=0,1,"NULL","test_0&h5fb4XQhOoD","B210DD9F749288AE7F8A485F0ABA0C0C05677A91",0,0,""
  AT+MQTTCLIENTID=0,"123456|securemode=3\,signmethod=hmacsha1|"
  AT+MQTTCONN=0,"h5fb4XQhOoD.iot-as-mqtt.cn-shanghai.aliyuncs.com",1883,1
  AT+MQTTSUB=0,"/sys/h5fb4XQhOoD/test_0/thing/service/property/set",1
 
* @param  {void} 
* @return {uint8_t } : if success,return (uint8_t)OPERATION_SUCCESS
* @author: leeqingshui 
*/
uint8_t Connct_aliyun_iot(void)
{
	printf("The Internet of Things cloud platform is connected\r\n");
	
	uint8_t ret = (uint8_t)OPERATION_SUCCESS;
	int connect_times = 0;
	
	/* Restore the factory default mode */
	if(ESP8266_AT_RESTORE() != (uint8_t)OPERATION_SUCCESS)
	{
		ret = (uint8_t)OPERATION_ERROR;
		return ret;
	}

	/* Set to client mode */
	if(ESP8266_Net_Mode_Choose(STA) != (uint8_t)OPERATION_SUCCESS)
	{
		ret = (uint8_t)OPERATION_ERROR;
		return ret;
	}
	
	/* Connect to a wireless network */
	while((!ESP8266_JoinAP(WIFI_NAME, WIFI_KEY)) && connect_times<10)
	{
		connect_times++;
		ret = ESP8266_JoinAP(WIFI_NAME, WIFI_KEY);
	}
	if(ret != (uint8_t)OPERATION_SUCCESS)
		return ret;
	connect_times = 0;
	
	/* Set the time domain and SNTP server */
	while((!ESP8266_Set_SNTP(8 , SNTP_SERVER_0 , SNTP_SERVER_1 , SNTP_SERVER_2)) && connect_times<10)
	{
		connect_times++;
		ret = ESP8266_Set_SNTP(8 , SNTP_SERVER_0 , SNTP_SERVER_1 , SNTP_SERVER_2);
	}
	if(ret != (uint8_t)OPERATION_SUCCESS)
		return ret;
	connect_times = 0;
	
	/* MQTT configures user attributes */
	if(ESP8266_MQTTUSERCFG( CLIENT_ID, MQTT_Username, MQTT_Password) != (uint8_t)OPERATION_SUCCESS)
	{
		ret = (uint8_t)OPERATION_ERROR;
		return ret;
	}
	
	/* Set the MQTT client ID : Generated by aliyun Iot platform configuration tool */
	if(ESP8266_MQTTSETCLIENTID(MQTT_User_client_id) != (uint8_t)OPERATION_SUCCESS)
	{
		ret = (uint8_t)OPERATION_ERROR;
		return ret;
	}
	
	/* Connect to the specified MQTT server */
	if(ESP8266_MQTTCONN( MQTT_Server_IP, MQTT_Server_PORT) != (uint8_t)OPERATION_SUCCESS)
	{
		ret = (uint8_t)OPERATION_ERROR;
		return ret;
	}
	
    /* Connect to the specified MQTT server */
	if(ESP8266_MQTTSUB(PROPERTY_SET) != (uint8_t)OPERATION_SUCCESS)
	{
		ret = (uint8_t)OPERATION_ERROR;
		return ret;
	}
	
	printf("The cloud platform is successfully connected\r\n");
	
	return ret;
}

/** 
* @description: Gets the network connection status
* @param  {void} 
* @return {uint8_t } : if success,return (uint8_t)OPERATION_SUCCESS
* @author: leeqingshui 
*/
uint8_t Get_InternetLink_Status(void)
{
	uint8_t ret = (uint8_t)OPERATION_SUCCESS;

	Connect_Status_Stucrt.Internet_Link_Status = ESP8266_Get_LinkStatus ();
	
	if(Connect_Status_Stucrt.Internet_Link_Status>4)
	{
		ret = (uint8_t)OPERATION_ERROR;
	}
	
	return ret;
}

/** 
* @description: Gets the MQTT connection server status
* @param  {void} 
* @return {uint8_t } : if success,return (uint8_t)OPERATION_SUCCESS
* @author: leeqingshui 
*/
uint8_t Get_ServerLink_Status(void)
{
	uint8_t ret = (uint8_t)OPERATION_SUCCESS;

	Connect_Status_Stucrt.MQTTS_Link_tatus = ESP8266_Get_MQTTStatus ();
	
	if(Connect_Status_Stucrt.MQTTS_Link_tatus>6)
	{
		ret = (uint8_t)OPERATION_ERROR;
	}
	
	return ret;
}

/** 
* @description: Upload data to the server
* @param  {void   } 
* @return {uint8_t} : if success,return (uint8_t)OPERATION_SUCCESS
* @author: leeqingshui 
*/
__weak uint8_t UploadData_To_Server(void)
{
	uint8_t ret = (uint8_t)OPERATION_SUCCESS;
	
	char message[256]={0};
	
	sprintf(message,"{\"method\":\"thing.event.property.post\",\"id\":\"0000000001\",\"params\":{\"mtemp\":%d},\"version\":\"1.0.0\"}",Upload_SensorDate_struct.Temp);
	
	ESP8266_MQTTPUB(PROPERTY_POST,message);
	
	return ret;
}

/** 
* @description: Fixed heartbeat packets are sent to the server
* @param  {char *} str : String information
* @return {uint8_t } : if success,return (uint8_t)OPERATION_SUCCESS
* @author: leeqingshui 
*/
__weak uint8_t Send_Heart_Server(void)
{
	uint8_t ret = (uint8_t)OPERATION_SUCCESS;

	ret = ESP8266_Send_Heart();

	return ret;
}

/** 
* @description: connect iot task function
* @param  {void*} 
* @return {void } 
* @author: leeqingshui 
*/
void Connect_Iot_Task(void* parameter)
{
	BaseType_t xReturn = pdPASS;
	
	while(1)
	{
        /* Sends network status data to the message queue */
	    xReturn = xQueueSend(	Internet_Status_Queue, 
								&Connect_Status_Stucrt,
								500);       
		/* Description Sending network status data succeeded */
        if(pdPASS == xReturn)
			printf("Description Sending network status data succeeded\r\n");
		
		/* Receiving sensor data */
		xReturn = xQueuePeek( 	Sensor_Data_Queue,  
							    &Upload_SensorDate_struct,     
                                500); 
		/* Receiving sensor data succeeded */
		if(pdPASS == xReturn)
			printf("Receiving sensor data succeeded\r\n");
		
		/* Update the data */
		UploadData_To_Server();
		
		printf("connect iot task task Running\r\n");
		vTaskDelay(5000);
	}
}
